import tkinter as tk
from PIL import Image
import pystray
import threading
import tkinter.simpledialog
import tkinter.messagebox
from copy import deepcopy
import json
import webbrowser

# 指定要保存的文件路径和名称
set_data_path = 'set_data.json'


class BloodBars:
    def __init__(self, main_window, canvas, screen_width, screen_height, initial_data=None):
        self.main_window = main_window
        self.canvas = canvas
        self.screen_width = screen_width
        self.screen_height = screen_height

        # 默认血条参数
        self.default_data = {
            'old_screen_width': screen_width,
            'old_screen_height': screen_height,
            'percentage': [0.25, 0.41, 0.54, 0.64],
            'colors': ['blue', 'yellow', 'orange', 'red'],
            'texts': ['5', '6', '7', '8'],
            'per_width': 0.215,
            'per_height': 0.018,
            'per_y': 38,
            'bar_width': screen_width * 0.215,
            'bar_height': screen_height * 0.018,
            'bar_y': screen_height - (screen_height * 0.018) - 38,
            'bor_width': 2,
            'lines_width': 3,
            'text_size': 16,
            'text_line_distance': 18,
            'blood_line_visible': True,
            'lines_visible': True,
            'texts_visible': True,
            'center_point_visible': True,
        }

        # 尝试加载保存的数据
        self.current_data = self.load_saved_data() if initial_data is None else initial_data

        # 初始化显示状态
        self.blood_line_visible = self.current_data['blood_line_visible']
        self.lines_visible = self.current_data['lines_visible']
        self.texts_visible = self.current_data['texts_visible']
        self.center_point_visible = self.current_data['center_point_visible']

    def load_saved_data(self):
        """加载保存的数据，如果文件不存在则使用默认数据"""
        try:
            with open(set_data_path, 'r') as f:
                return json.load(f)
        except (FileNotFoundError, json.JSONDecodeError):
            print("使用默认数据")
            return deepcopy(self.default_data)

    def first_open(self):
        """判断是否是第一次打开或屏幕尺寸改变"""
        old_width = self.current_data['old_screen_width']
        old_height = self.current_data['old_screen_height']
        return old_width != self.screen_width or old_height != self.screen_height

    def draw_blood_bars(self):
        """绘制血条"""
        self.canvas.delete("all")

        # 计算血条位置
        if self.first_open():
            self.update_bar_position()

        # 绘制血条框
        self.draw_blood_frame()

        # 绘制竖线和文字
        self.draw_lines_and_texts()

        # 绘制中心点
        if self.center_point_visible:
            self.draw_center_point()

    def update_bar_position(self):
        """更新血条位置"""
        self.current_data.update({
            'old_screen_width': self.screen_width,
            'old_screen_height': self.screen_height,
            'bar_width': self.screen_width * self.current_data['per_width'],
            'bar_height': self.screen_height * self.current_data['per_height'],
            'bar_y': self.screen_height - (self.screen_height * self.current_data['per_height']) - self.current_data[
                'per_y']
        })

    def draw_blood_frame(self):
        """绘制血条框"""
        if not self.blood_line_visible:
            return

        bar_width = self.current_data['bar_width']
        bar_height = self.current_data['bar_height']
        bar_y = self.current_data['bar_y']

        blood_start_x = (self.screen_width - bar_width) / 2
        blood_end_x = blood_start_x + bar_width

        self.canvas.create_rectangle(
            blood_start_x - 2, bar_y - 2,
            blood_end_x + 2, bar_y + bar_height + 2,
            fill="green",
            outline="black",
            width=self.current_data['bor_width']
        )

    def draw_lines_and_texts(self):
        """绘制竖线和文字"""
        bar_width = self.current_data['bar_width']
        bar_height = self.current_data['bar_height']
        bar_y = self.current_data['bar_y']

        blood_start_x = (self.screen_width - bar_width) / 2

        for i, percentage in enumerate(self.current_data['percentage']):
            x_start = blood_start_x + (bar_width * percentage)

            # 绘制竖线
            if self.lines_visible:
                self.canvas.create_line(
                    x_start, bar_y - 2,
                    x_start, bar_y + bar_height + 2,
                    fill=self.current_data['colors'][i],
                    width=self.current_data['lines_width']
                )

            # 绘制文字
            if self.texts_visible:
                self.canvas.create_text(
                    x_start, bar_y - self.current_data['text_line_distance'],
                    text=self.current_data['texts'][i],
                    fill=self.current_data['colors'][i],
                    font=("Segoe UI", self.current_data['text_size'])
                )

    def draw_center_point(self):
        """绘制中心点"""
        center_x = self.screen_width // 2
        center_y = self.screen_height // 2
        radius = 2
        self.canvas.create_oval(
            center_x - radius, center_y - radius,
            center_x + radius, center_y + radius,
            fill="red"
        )


class HealthBarWindow:
    def __init__(self):
        # 创建主窗口
        self.main_window = tk.Tk()
        self.main_window.title("Health Bar")

        # 获取屏幕尺寸
        self.screen_width = self.main_window.winfo_screenwidth()
        self.screen_height = self.main_window.winfo_screenheight()
        print(f"屏幕宽度: {self.screen_width}, 屏幕高度: {self.screen_height}")

        # 设置窗口属性
        self.main_window.attributes("-fullscreen", True)
        self.main_window.overrideredirect(True)
        self.main_window.attributes("-topmost", True)
        self.main_window.attributes("-transparentcolor", "green")

        # 创建画布
        self.canvas = tk.Canvas(self.main_window, bg='green', highlightthickness=0)
        self.canvas.pack(fill=tk.BOTH, expand=True)

        # 初始化血条
        self.blood_bars = BloodBars(self.main_window, self.canvas, self.screen_width, self.screen_height)
        self.blood_bars.draw_blood_bars()

        # 创建系统托盘图标
        self.create_systray_icon()

    def start(self):
        if self.blood_bars.first_open():
            self.set_data()
        self.main_window.mainloop()

    def create_systray_icon(self):
        """创建系统托盘图标"""
        menu = (
            pystray.MenuItem('显示全部', self.show_window),
            pystray.MenuItem('显示血条框', self.show_blood_line),
            pystray.MenuItem('显示提示条', self.show_lines),
            pystray.MenuItem('显示数字', self.show_texts),
            pystray.MenuItem('显示中心点', self.show_center_point),

            pystray.Menu.SEPARATOR,

            pystray.MenuItem('隐藏全部', self.hide_window),
            pystray.MenuItem('隐藏血条框', self.hide_blood_line),
            pystray.MenuItem('隐藏提示条', self.hide_lines),
            pystray.MenuItem('隐藏数字', self.hide_texts),
            pystray.MenuItem('隐藏中心点', self.hide_center_point),

            pystray.Menu.SEPARATOR,
            pystray.MenuItem('使用说明', self.instructions),
            pystray.MenuItem('设置参数', self.set_data),
            pystray.Menu.SEPARATOR,
            pystray.MenuItem('关于', self.show_about),
            pystray.MenuItem('退出', self.quit_window)
        )

        image = Image.open("signpost_fill.ico")
        self.icon = pystray.Icon("icon", image, "抗毒提示条", menu)
        threading.Thread(target=self.icon.run, daemon=True).start()

    def save_data(self):
        """保存当前设置到文件"""
        with open(set_data_path, 'w') as f:
            json.dump(self.blood_bars.current_data, f, indent=4)
        print(f"数据已保存到：{set_data_path}")

    def toggle_element(self, element_type, visible):
        """切换元素显示状态"""
        setattr(self.blood_bars, f"{element_type}_visible", visible)
        self.blood_bars.current_data[f"{element_type}_visible"] = visible
        self.blood_bars.draw_blood_bars()
        self.save_data()

    def show_window(self):
        self.toggle_all_elements(True)

    def hide_window(self):
        self.toggle_all_elements(False)

    def toggle_all_elements(self, visible):
        """切换所有元素显示状态"""
        elements = ['blood_line', 'lines', 'texts', 'center_point']
        for element in elements:
            self.toggle_element(element, visible)

    def show_blood_line(self):
        self.toggle_element('blood_line', True)

    def hide_blood_line(self):
        self.toggle_element('blood_line', False)

    def show_lines(self):
        self.toggle_element('lines', True)

    def hide_lines(self):
        self.toggle_element('lines', False)

    def show_texts(self):
        self.toggle_element('texts', True)

    def hide_texts(self):
        self.toggle_element('texts', False)

    def show_center_point(self):
        self.toggle_element('center_point', True)

    def hide_center_point(self):
        self.toggle_element('center_point', False)

    def instructions(self):
        webbrowser.open("https://mjj.pub/archives/pubgkang-du-ti-shi-tiao-shi-yong-shuo-ming")

    def set_data(self):
        """打开设置窗口"""

        def apply_settings():
            try:
                # 获取用户输入
                percentage_str = entry_percentage.get().strip()
                colors_str = entry_colors.get().strip()
                texts_str = entry_texts.get().strip()
                per_width_str = entry_per_width.get().strip()
                per_height_str = entry_per_height.get().strip()
                per_y_str = entry_per_y.get().strip()
                text_size_str = entry_text_size.get().strip()
                lines_width_str = entry_lines_width.get().strip()
                bor_width_str = entry_bor_width.get().strip()
                text_line_distance_str = entry_text_line_distance.get().strip()

                # 检查输入是否为空
                if not percentage_str or not colors_str or not texts_str:
                    raise ValueError("输入不能为空")

                # 将百分比字符串分割并转换为浮点数
                percentage = []
                for p in percentage_str.split(','):
                    p = p.strip()
                    if not p:
                        raise ValueError("百分比不能为空")
                    try:
                        percentage.append(float(p))
                    except ValueError:
                        raise ValueError(f"无法将'{p}'转换为浮点数")

                # 将颜色字符串分割
                colors = colors_str.split(',')
                colors = [c.strip() for c in colors if c.strip()]

                # 将文字字符串分割
                texts = texts_str.split(',')
                texts = [t.strip() for t in texts if t.strip()]

                # 验证百分比、颜色和文字数量一致
                if len(percentage) != len(colors) or len(percentage) != len(texts):
                    raise ValueError("百分比、颜色和文字数量必须一致")

                # 转换其他参数
                try:
                    per_width = float(per_width_str)
                    per_height = float(per_height_str)
                    per_y = float(per_y_str)
                    text_size = int(text_size_str)
                    lines_width = float(lines_width_str)
                    bor_width = int(bor_width_str)
                    text_line_distance = int(text_line_distance_str)
                except ValueError as e:
                    raise ValueError(f"无法转换参数：{str(e)}")

                # 更新数据
                self.blood_bars.current_data.update({
                    'old_screen_width': self.screen_width,
                    'old_screen_height': self.screen_height,
                    'percentage': percentage,
                    'colors': colors,
                    'texts': texts,
                    'per_width': per_width,
                    'per_height': per_height,
                    'per_y': per_y,
                    'bar_width': self.screen_width * per_width,
                    'bar_height': self.screen_height * per_height,
                    'bar_y': self.screen_height - (self.screen_height * per_height) - per_y,
                    'bor_width': bor_width,
                    'lines_width': lines_width,
                    'text_size': text_size,
                    'text_line_distance': text_line_distance
                })

                # 重新绘制
                self.blood_bars.draw_blood_bars()
                self.save_data()

            except Exception as e:
                tkinter.messagebox.showerror("错误", str(e))

        top = tk.Toplevel(self.main_window)
        top.title("设置参数")
        top.wm_iconbitmap("signpost_fill.ico")
        x = (self.screen_width - 400) // 2
        y = (self.screen_height - 500) // 2
        top.geometry(f"400x500+{x}+{y}")

        current_data = self.blood_bars.current_data

        # 创建输入控件
        def create_input(label_text, var_name):
            tk.Label(top, text=label_text).pack()
            entry = tk.Entry(top)

            # 特殊处理列表类型数据（如 percentage、colors、texts）
            if isinstance(current_data[var_name], list):
                # 将列表转换为逗号分隔的字符串（无方括号）
                value = ",".join(map(str, current_data[var_name]))
            else:
                value = str(current_data[var_name])

            entry.insert(0, value)  # 关键修复点
            entry.pack()
            return entry

        entry_percentage = create_input("提示条百分比（逗号分隔）", 'percentage')
        entry_colors = create_input("颜色（逗号分隔）", 'colors')
        entry_texts = create_input("文字（逗号分隔）", 'texts')
        entry_text_size = create_input("文字大小", 'text_size')
        entry_text_line_distance = create_input("文字与边框距离", 'text_line_distance')
        entry_bor_width = create_input("边框宽度", 'bor_width')
        entry_lines_width = create_input("提示条宽度", 'lines_width')
        entry_per_width = create_input("血条宽度比例", 'per_width')
        entry_per_height = create_input("血条高度比例", 'per_height')
        entry_per_y = create_input("血条垂直位置", 'per_y')

        # 操作按钮
        button_frame = tk.Frame(top)
        button_frame.pack(pady=10)

        tk.Button(button_frame, text="应用", command=apply_settings).pack(side=tk.LEFT, padx=5)
        tk.Button(button_frame, text="关闭", command=top.destroy).pack(side=tk.LEFT, padx=5)

    def show_about(self):
        """显示关于窗口"""
        about_window = tk.Toplevel()
        about_window.title("关于")
        about_window.wm_iconbitmap("signpost_fill.ico")
        about_window.resizable(False, False)

        x = (self.screen_width - 400) // 2
        y = (self.screen_height - 350) // 2
        about_window.geometry(f"400x350+{x}+{y}")

        main_frame = tk.Frame(about_window)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=20, pady=20)

        tk.Label(main_frame, text="PUBG抗毒提示条", font=("Arial", 14, "bold")).pack(pady=10)
        tk.Label(main_frame, text="版本: V0.1.2").pack()
        tk.Label(main_frame, text="作者: 江小鉴").pack(pady=5)
        tk.Label(main_frame, text="使用技术: python、tkinter、pystray").pack()

        text = tk.Text(main_frame, font=("Arial", 10), height=7, width=50, borderwidth=0)
        text.insert(tk.END, """最近沉迷于《PUBG》的抗毒吃鸡模式，但每次都被毒圈搞得手忙脚乱，总是忘记在什么阶段该打急救包。
为了帮助自己和像我一样的玩家更好地应对毒圈的挑战，我开发了这款 PUBG 抗毒提示条应用。""")
        text.pack(pady=5)
        text.config(state=tk.DISABLED)
        text.configure(bg=about_window.cget("bg"))

        tk.Label(main_frame, text="© 2025 江小鉴.保留部分权力").pack()

    def quit_window(self):
        """退出程序"""
        self.icon.stop()
        self.main_window.quit()
        self.main_window.destroy()


if __name__ == '__main__':
    app = HealthBarWindow()
    app.start()